<?php

namespace App\Imports;

use App\Http\Controllers\Asset\AssetHelper;
use App\Models\Asset;
use App\Models\AssetAffiliation;
use App\Models\AssetBrand;
use App\Models\AssetKeeper;
use App\Models\AssetLocation;
use App\Models\AssetVendor;
use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
use Maatwebsite\Excel\Concerns\OnEachRow;

use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Row;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use Validator;

class AssetsImport implements OnEachRow
{
    use AssetHelper;
    use AssetImportTrait;


    /**
     * AssetsImport constructor.
     */
    public function __construct()
    {
        // 需要设置local, 否则Validator处理中文会有问题
        setlocale(LC_ALL, "zh_CN.UTF-8");
    }


    /**
     * @param Row $row
     * @throws Exception
     */
    public function onRow(Row $row)
    {
        $rowIndex = $row->getIndex();
        // skip heading row
        if ($rowIndex == 1) {
            return;
        }

        $row = $row->toArray();

        $this->createAsset($row, $rowIndex);
    }

    /**
     * @param Row $row
     */
    private function validateAsset(Array $row, $rowIndex, $dateFormat): Collection
    {

        $availablePrimaryCategories = $this->getAllPrimaryCategoryNames() ?? [];
        $v1 = Validator::make($row, [
            '0' => "required", // 名称
            '1' => "nullable", // 物品编码
            '2' => ['required', Rule::in($availablePrimaryCategories)], // 主类
            '3' => "required|string", // 副类
            '4' => "required|string", // 品牌
            '5' => "nullable", // SN序列号
            '6' => [Rule::in($this->getAssetStatusNames())], // 状态
            '7' => "required|string", // 归属
            '8' => "required|string", // 保管人
            '9' => "nullable|numeric", // 市场价
            '10' => "nullable|numeric", // 购入价
            '11' => "nullable|date|date_format:$dateFormat", // 购入日期
            '12' => "nullable", // 供应商
            '13' => "nullable", // 仓库
        ], [
            '2' => ":attribute【 C$rowIndex 】 :input 非法 请使用如下可选值 【 :values 】",
            'required' => "行: $rowIndex  【 :attribute 】数据是必须的",
        ], [
            '2' => '主类',
            '3' => '副类',
            '4' => '品牌',
            '7' => '归属',
            '8' => '保管人'
        ])->errors();

        // 检查主副类是否满足关系
        $primaryCategoryName = $row[2] ?? '_undefined_';
        $validSubCategories = $this->getSubCategoriesByPrimaryCategoryName($primaryCategoryName)->pluck("name") ?? [];
        $subCategoryName = $row[3] ?? "_undefined_";
        $v2 = Validator::make([$subCategoryName], [
            "0" => [Rule::in($validSubCategories)]
        ], [
            "0" => "主类 【 C$rowIndex 】 和 副类 【 D$rowIndex 】 关系错误"
        ])->errors();
        return collect($v1)->merge($v2);
    }

    /**
     * @param Row $row
     * @param int $rowIndex
     * @throws Exception
     */
    private function createAsset(Array $row, int $rowIndex): void
    {
        // convert date for bid_date
        $fDate = null;
        $dateFormat = config('app.date_format');
        try {
            $formatedDate = Date::excelToDateTimeObject($row[11]);
            $fDate = $formatedDate->format($dateFormat);
        } catch (\Exception $e) {
        }
        $row[11] = $fDate;

        $errors = $this->validateAsset($row, $rowIndex, $dateFormat);
        if ($errors->count() > 0) {
            throw new Exception($errors);
        }

        // required
        $brandName = $row[4];
        $brand_id = $this->getOrNewBrand($brandName)->id;

        $affiliationName = $row[7];
        $affiliation_id = $this->getOrNewAffiliation($affiliationName)->id;
        $keeperName = $row[8];
        $keeper_id = $this->getOrNewKeeper($keeperName)->id;

        $primaryCategoryId = $this->getPrimaryCategoryByName($row[2])['id'];
        $assetData = [
            "name" => $row[0],
            "product_model_number" => $row[1],
            "category_id" => $primaryCategoryId,
            "sub_category_id" => $this->getSubCategoryByPrimaryCategoryIdAndName($primaryCategoryId, $row[3])['id'],
            "brand_id" => $brand_id,
            "sn" => $row[5],
            "status_id" => $this->getAssetStatusByName($row[6])['id'],
            "affiliation_id" => $affiliation_id,
            "keeper_id" => $keeper_id,
            "marking_price" => $row[9] ?? 0,
            "bid_price" => $row[10] ?? 0,
        ];

        if (!empty($fDate)) {
            $assetData['bid_date'] = $fDate;
        }

        // optional
        // 供应商
        $vendor_id = null;
        $vendorName = $row[12];
        if (!empty($vendorName) && $vendorName != '无') {
            $vendor_id = $this->getOrNewVendor($vendorName)->id;
        }
        if (!empty($vendor_id)) {
            $assetData['vendor_id'] = $vendor_id;
        }
        // 仓库

        $locationName = $row[13];
        $location_id = null;
        if (!empty($locationName)) {
            $location_id = $this->getOrNewLocation($locationName)->id;
        }
        if (!empty($location_id)) {
            $assetData['location_id'] = $location_id;
        }
        Asset::create($assetData);
    }

}
